
package peerToPeerFacebook.proj;


import java.io.Serializable;
import java.util.HashSet;

/**
 * This class implements the asynchronous equivalent of a for loop for (int i =
 * 0; i< users.length; i++) { postmessage(users[i], message); }
 * 
 * We keep track of the last friend to which the message was sent. In the
 * callback, we send the message to the next friend, and increment the iteration
 * coutner.
 * 
 */
public class PostMessageToAllFriends implements IResultCallback
{
    private int count;
    private String message;
    String[] friendNames;
    String userName;
    private boolean sentToAllSuccessfully;
    public static final String FriendFileSuffix = "_friends.txt";
    protected IResultCallback result = null;
    public FBNode node;
    public FacebookMethods fbClass;
    private String format = "***************";
    HashSet<Integer> serverList = new HashSet<Integer>();
    RemoteInvoker client;

    public PostMessageToAllFriends(String message, String userName, FBNode node,
                                   FacebookMethods fbClass)
    {
        ArgumentValidator.IsNotNullOrEmpty("message", message);

        this.message = message;
        this.count = 0;
        this.sentToAllSuccessfully = true;
        this.userName = userName;
        this.node = node;
        this.fbClass = fbClass;
        this.client = node.getPaxosInvoker();

    }

    /**
     * helper method for printing the result of the failed RPC call
     */

    public void printErrorMsg()
    {
        System.out.println(" \n\n" + format + " The requested operation failed " + format +
                           "\n\n");
    }

    /**
     * This method start a transaction and get the content of the friends file
     * so that it can send messages to all the friends of the User
     */
    public void start()
    {
        // We need to get the Server ID of the user and the corresponding RPC
        // Client
       /* int userServerID = fbClass.mapUser(userName);*/
       /* int userServerID = 1;
        final RPCClient userRPCClient = node.getRPCClient(userServerID);*/
        

        client.invoke(IServerFileIO.GetFileContentsMethodName,
                             new Serializable[] {userName + FriendFileSuffix},
                             new IResultCallback()
                             {
                                 public void resultCallback(Status status, Serializable result)
                                 {
                                     if (status == Status.Success)
                                     {
                                         String friendList = result.toString();
                                         friendNames = friendList.split("\r\n");
                                         sendMsg();
                                     }
                                     else
                                     {
                                         printErrorMsg();
                                     }

                                 }
                             });
    }

    public void sendMsg()
    {
        /*int friendServerID = fbClass.mapUser(this.friendNames[count]);*/
        
        /*int friendServerID = 1;

        RPCClient friendRPCClient = node.getRPCClient(friendServerID);
*/
        client.invoke(IServerFileIO.AppendContentsToFileMethodName,
                               new Serializable[] {
                                       this.friendNames[this.count] +
                                               FacebookMethods.MessagesFileSuffix,
                                       this.message + "\r\n"}, this);
    }

    @Override
    public void resultCallback(Status status, Serializable result)
    {
        if (status != Status.Success)
        {
            this.sentToAllSuccessfully = false;
        }

        this.count++;
        if (this.count < this.friendNames.length)
        {
            /*int friendServerID = fbClass.mapUser(this.friendNames[count]);*/
           /* int friendServerID = 1;
            RPCClient friendRPCClient = node.getRPCClient(friendServerID);*/

            client.invoke(IServerFileIO.AppendContentsToFileMethodName,
                                   new Serializable[] {
                                           this.friendNames[this.count] +
                                                   FacebookMethods.MessagesFileSuffix,
                                           this.message + "\r\n"}, this);
        }
        else
        {
            if (this.sentToAllSuccessfully)
            {
                System.out.println("\n\n" + format + "Successfully sent message to all !" +
                                   format + "\n\n");
            }
            else
            {
                System.out.println(" \n\n" + format +
                                   " The message couldn't be posted to all friends. " +
                                   format + "\n\n");
            }
        }
    }
}
